bitkeeper revision 1.1770 (42c2d66cG6YTU0WhG1b97E-InSNWWA)
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 29 Jun 2005 17:12:12 +0000 (17:12 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 29 Jun 2005 17:12:12 +0000 (17:12 +0000)
Ensure global variables required by get_s_time() are initialised before
first use. Rejuggle bootstrap code slightly.
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/nmi.c
xen/arch/x86/setup.c
xen/arch/x86/time.c

index 0e03b6a674873fce412cea287bfbdb3ead0a61d9..a0b11f9e1fa4f8be81d6719412f67acf9a40f7a4 100644 (file)
@@ -240,7 +240,6 @@ void __pminit setup_apic_nmi_watchdog(void)
     }
 
     init_ac_timer(&nmi_timer[cpu], nmi_timer_fn, NULL, cpu);
-    nmi_timer_fn(NULL);
 
     nmi_pm_init();
 }
@@ -257,18 +256,33 @@ static unsigned int watchdog_on;
 void watchdog_disable(void)
 {
     unsigned long flags;
+
     spin_lock_irqsave(&watchdog_lock, flags);
+
     if ( watchdog_disable_count++ == 0 )
         watchdog_on = 0;
+
     spin_unlock_irqrestore(&watchdog_lock, flags);
 }
 
 void watchdog_enable(void)
 {
+    unsigned int  cpu;
     unsigned long flags;
+
     spin_lock_irqsave(&watchdog_lock, flags);
+
     if ( --watchdog_disable_count == 0 )
+    {
         watchdog_on = 1;
+        /*
+         * Ensure periodic heartbeats are active. We cannot do this earlier
+         * during setup because the timer infrastructure is not available. 
+         */
+        for_each_online_cpu ( cpu )
+            set_ac_timer(&nmi_timer[cpu], NOW());
+    }
+
     spin_unlock_irqrestore(&watchdog_lock, flags);
 }
 
index 1fb131b2c866dc12a2af2e4b7eeffabd0ac00a35..e74adf86e81bc7e6290e9aa4cac2882a257dfd2d 100644 (file)
@@ -75,7 +75,7 @@ unsigned long xenheap_phys_start, xenheap_phys_end;
 extern void arch_init_memory(void);
 extern void init_IRQ(void);
 extern void trap_init(void);
-extern void time_init(void);
+extern void early_time_init(void);
 extern void ac_timer_init(void);
 extern void initialize_keytable(void);
 extern void early_cpu_init(void);
@@ -184,7 +184,7 @@ static void __init start_of_day(void)
 
     ac_timer_init();
 
-    time_init();
+    early_time_init();
 
     arch_init_memory();
 
@@ -205,14 +205,19 @@ static void __init start_of_day(void)
     for_each_cpu ( i )
         cpu_set(i, cpu_present_map);
 
-    /* Sanity: We ought to be taking interrupts by now. */
-    local_irq_enable();
+    /*
+     * Initialise higher-level timer functions. We do this fairly late
+     * (post-SMP) because the time bases and scale factors need to be updated 
+     * regularly, and SMP initialisation can cause a long delay with 
+     * interrupts not yet enabled.
+     */
+    init_xen_time();
 
     initialize_keytable();
 
     serial_init_postirq();
 
-    init_xen_time();
+    BUG_ON(!local_irq_is_enabled());
 
     for_each_present_cpu ( i )
     {
index acc5979c2bd2262b62c4a3e723564c8352df8337..5cd738bcdea0c64088fd86baaa59f8364d6effc8 100644 (file)
@@ -239,6 +239,8 @@ static inline u64 get_time_delta(void)
     u32      low;
     u64      delta, tsc;
 
+    ASSERT(st_scale_f || st_scale_i);
+
     rdtscll(tsc);
     low = (u32)(tsc >> rdtsc_bitshift);
     delta_tsc = (s32)(low - shifted_tsc_irq);
@@ -349,13 +351,17 @@ int __init init_xen_time()
     st_scale_f = scale & 0xffffffff;
     st_scale_i = scale >> 32;
 
+    local_irq_disable();
+
     /* System time ticks from zero. */
     rdtscll(full_tsc_irq);
     stime_irq = (s_time_t)0;
     shifted_tsc_irq = (u32)(full_tsc_irq >> rdtsc_bitshift);
 
     /* Wallclock time starts as the initial RTC time. */
-    wc_sec  = get_cmos_time();
+    wc_sec = get_cmos_time();
+
+    local_irq_enable();
 
     printk("Time init:\n");
     printk(".... cpu_freq:    %08X:%08X\n", (u32)(cpu_freq>>32),(u32)cpu_freq);
@@ -367,7 +373,7 @@ int __init init_xen_time()
 
 
 /* Early init function. */
-void __init time_init(void)
+void __init early_time_init(void)
 {
     unsigned long ticks_per_frac = calibrate_tsc();